#include <iostream>
#include <fstream>
#include <string>
#include <cctype>  // 用于字符处理（原代码中toLowerCase备用）

using namespace std;

// 函数声明
void encryptFile(ifstream& input, ofstream& output, const string& key);
void decryptFile(ifstream& input, ofstream& output, const string& key);
void toLowerCase(string& str);  // 备用功能（原代码逻辑保留）

int main() {
    string inputFile, outputFile, key;
    int choice;

    cout << "=== 文件加密解密工具 ===" << endl;
    cout << "请选择操作：" << endl;
    cout << "1. 加密文件（明文 → 密文）" << endl;
    cout << "2. 解密文件（密文 → 明文）" << endl;
    cout << "请输入选择 (1 或 2): ";
    cin >> choice;
    cin.ignore();  // 清除输入缓冲区中的换行符

    if (choice != 1 && choice != 2) {
        cerr << "错误：无效的选择！" << endl;
        return 1;
    }

    // 获取文件名
    cout << "请输入输入文件名: ";
    getline(cin, inputFile);  // 使用getline读取带空格的路径

    cout << "请输入输出文件名: ";
    getline(cin, outputFile);

    // 获取密钥
    cout << "请输入密钥: ";
    getline(cin, key);

    if (key.empty()) {  // 使用string的empty()判断空字符串
        cerr << "错误：密钥不能为空！" << endl;
        return 1;
    }

    // 打开文件（二进制模式，与原代码保持一致）
    ifstream fpin(inputFile, ios::binary);  // C++输入文件流
    ofstream fpout(outputFile, ios::binary); // C++输出文件流

    if (!fpin.is_open()) {  // 使用is_open()判断文件是否打开成功
        cerr << "错误：无法打开输入文件 '" << inputFile << "'" << endl;
        return 1;
    }
    if (!fpout.is_open()) {
        cerr << "错误：无法创建输出文件 '" << outputFile << "'" << endl;
        fpin.close();
        return 1;
    }

    // 根据选择执行加密或解密
    if (choice == 1) {
        cout << "正在进行加密..." << endl;
        encryptFile(fpin, fpout, key);
        cout << "文件加密完成！明文 '" << inputFile << "' → 密文 '" << outputFile << "'" << endl;
    }
    else {
        cout << "正在进行解密..." << endl;
        decryptFile(fpin, fpout, key);
        cout << "文件解密完成！密文 '" << inputFile << "' → 明文 '" << outputFile << "'" << endl;
    }

    // 关闭文件（C++流会自动关闭，但显式关闭更规范）
    fpin.close();
    fpout.close();

    return 0;
}

// 加密文件函数（使用C++流操作）
void encryptFile(ifstream& input, ofstream& output, const string& key) {
    char ch;
    size_t i = 0;  // 使用size_t更适合索引
    size_t keyLen = key.length();  // string的length()获取长度

    // 读取到文件末尾（eof()判断）
    while (input.get(ch)) {  // get()读取单个字符（包括空格、换行等）
        // 异或运算加密（与原代码逻辑一致）
        output.put(ch ^ key[i % keyLen]);
        i++;
    }
}

// 解密文件函数（异或加密的解密与加密过程相同）
void decryptFile(ifstream& input, ofstream& output, const string& key) {
    encryptFile(input, output, key);  // 直接复用加密函数
}

// 将字符串转换为小写（备用功能，原代码逻辑保留）
void toLowerCase(string& str) {
    for (char& c : str) {  // 范围for循环遍历字符串
        c = tolower(c);
    }
}